package com.yd.cfckc.util;

import org.apache.log4j.Logger;

import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author cuiyufeng
 * @email cuiyufeng1458@yundasys.com
 * @date 2020/10/16 3:41 下午
 */
public class PostSendTool {
    /**日志记录器*/
    private static Logger log = Logger.getLogger(PostSendTool.class);
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) throws Exception {
        //http://192.168.1.147:7001/wsq/opws_ls.jsp?op=gettime&txm=1200000000002
        System.out.println(sendMessage("http://qz.yundasys.com:45166/wsq/opws_ls.jsp?op=gettime&txm=1000805773732",""));

    }
    /**
     * 发送utf-8的数据请求，返回数据也为utf-8
     * @param url  发送的目标url
     * @return  请求的返回数据 一般返回数据格式为json或者xml格式
     * @throws Exception 执行可能抛出连接异常 或者 求情不合理
     * @author xuesheng
     */
    public static String sendMessage(String url ,String sendMsgData) throws ConnectException,Exception {
        return  sendMessage(url, sendMsgData, "UTF-8");
    }
    /**
     * 发送utf-8的数据请求，返回数据也为utf-8
     * @param url  发送的目标url
     * @param sendMsgData 发送的数据格式，xml格式 或者其他格式数据
     * @param charEncode 发送的数据字符编码
     * @return  请求的返回数据 一般返回数据格式为json或者xml格式
     * @throws Exception 执行可能抛出连接异常 或者 求情不合理
     * @author xuesheng
     */
    public static String sendMessage(String url ,String sendMsgData,String charEncode) throws ConnectException,Exception {
        StringBuffer reciveMsg = new StringBuffer();
        if("".equals(StringUtils.isJavaNull(url).trim())  ){
            throw new ConnectException("请求url 地址为空！");
        }
        if("".equals(StringUtils.isJavaNull(sendMsgData).trim())  ){
            log.warn("请求数据或报文为空！");
        }

        StringBuffer sendMsg = new StringBuffer(sendMsgData);
        BufferedReader reader = null;
        OutputStream output =null;
        InputStream inputStream = null;
        try {
            String strMessage = "";
            URL uploadServlet = new URL(url);

            HttpURLConnection servletConnection = (HttpURLConnection)uploadServlet.openConnection();

            // 设置连接参数
            servletConnection.setRequestMethod("POST");
            // 设置是否向httpUrlConnection输出，因为这个是post请求，参数要放在 http正文内，因此需要设为true, 默认情况下是false
            servletConnection.setDoOutput(true);
            // 设置是否从httpUrlConnection读入，默认情况下是true;
            servletConnection.setDoInput(true);
            // Post 请求不能使用缓存
            servletConnection.setUseCaches(false);

            //HttpURLConnection是基于HTTP协议的，其底层通过socket通信实现。如果不设置超时（timeout），
            //在网络异常的情况下，可能会导致程序僵死而不继续往下执行
            servletConnection.setConnectTimeout(60*1000); ///毫秒
            servletConnection.setReadTimeout(60*1000); ///毫秒

            servletConnection.setAllowUserInteraction(true);

            // 设定传送的内容类型是可序列化的java对象
            // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
            // servletConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");

            // 连接，从上述第2条中url.openConnection()至此的配置必须要在connect之前完成，
            //   servletConnection.connect();


            // 开启流，写入XML数据
            // 此处getOutputStream会隐含的进行connect(即：如同调用上面的connect()方法，
            // 所以在开发中不调用上述的connect()也可以)。

            log.info("发送数据到："+url);
            log.info("发送数据为："+sendMsg.toString());

            //采用三次请求 确保可以正常的连接到服务

            try{
                output = servletConnection.getOutputStream();
            }catch (java.net.ConnectException e1) {
                log.error("连接"+url+"失败，"+e1.getMessage()+";将进行第二次连接");
                try{
                    output = servletConnection.getOutputStream();
                }catch (java.net.ConnectException e2) {
                    log.error("连接"+url+"失败，"+e2.getMessage()+";将进行第三次连接");
                    try{
                        output = servletConnection.getOutputStream();
                    }catch (java.net.ConnectException e3) {
                        log.error("三次连接"+url+"失败，请求终止!"+e2.getMessage());
                        throw e3;
                    }
                }
            }
            output.write(sendMsg.toString().getBytes(charEncode));
            output.flush();
            output.close();

            // 上边的httpConn.getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义，
            // 既使对象输出流没有调用close()方法，下边的操作也不会向对象输出流写入任何数据.
            // 因此，要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据、
            // 重新发送数据(至于是否不用重新这些操作需要再研究)

            // 获取返回的数据 调用HttpURLConnection连接对象的getInputStream()函数,
            // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。 <===注意，实际发送请求的代码段就在这里
            inputStream = servletConnection.getInputStream();
            ///InputStreamReader read=new InputStreamReader(new FileInputStream(file),"UTF-8");
            reader = new BufferedReader(new InputStreamReader(inputStream,charEncode));
            while ((strMessage = reader.readLine()) != null) {
                reciveMsg.append(strMessage);
            }

            log.info(url+" 返回数据为："+reciveMsg.toString());

        } catch (java.net.ConnectException e) {
            log.error(e.getMessage());
            throw e;
        } finally {
            if(output != null){
                output.close();
            }
            if (reader != null) {
                reader.close();
            }
            if(inputStream != null){
                inputStream.close();
            }
        }
        return reciveMsg.toString();
    }
    /**
     * 预付款接口调用
     */
    public static String postUrl(String urlStr, String json){
        StringBuffer res = new StringBuffer();
        HttpURLConnection conn = null;
        BufferedWriter bw = null;
        BufferedReader br = null;
        try
        {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setUseCaches(false);//POST对应缓存为false
            conn.setConnectTimeout(30*1000);//连接超时30秒
            conn.setReadTimeout(30*1000);//读取超时30秒
            //conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(),"UTF-8"));
            bw.write(json);
            bw.flush();
            bw.close();
            if(conn.getResponseCode() == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
                String outStr = reader.readLine();
                while(null != outStr) {
                    res.append(outStr);
                    outStr=reader.readLine();
                }
            }
            br = new BufferedReader(new InputStreamReader(conn.getInputStream())) ;
            String out = null;
            while((out = br.readLine()) != null){
                res.append(out);
            }
            br.close();
        }
        catch (Exception e){
            log.error(e.getMessage());
        }finally{
            try {
                if( bw != null){ bw.close();}
                if( br != null){ br.close();}
                if( conn != null){ conn.disconnect();}
            } catch (IOException e) {}
        }
        return res.toString();
    }
}
